//
//  Entity.m
//  CompGraf2
//
//  Created by Juan Niosi on 09/08/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "Entity.h"

@implementation Entity
@synthesize colors, vertices, texture, uvs, normals;
@synthesize vertCount, bounds;

- (id)init
{
    self = [super init];
    if (self) {
        name = @"";
        colors = nil;
        vertices = nil;
        uvs = nil;
        texture = nil;
        children = [[NSMutableArray alloc] init];
        vertCount = 0;
        bounds = [[Bounds alloc] init];
    }
    
    return self;
}

- (id)initWithVertices:(GLfloat *)verts vertCount:(GLint)vCount setColor:(GLfloat *)cols
{
    self = [super init];
    if (self) {
        name = @"";
        colors = cols;
        vertices = verts;
        uvs = nil;
        texture = nil;
        children = [[NSMutableArray alloc] init];
        vertCount = vCount;
        normals = NULL;
        bounds = [[Bounds alloc] initWithEntity:self];
    }
    
    return self;
}

- (id)initWithVertices:(GLfloat *)verts vertCount:(GLint)vCount setTexture:(Texture *)tex setUVs:(GLfloat *)uvArray  setNormals:(GLfloat *)vNormals
{
    self = [super init];
    if (self) {
        colors = nil;
        vertices = verts;
        texture = tex;
        uvs = uvArray;
        children = nil;
        children = [[NSMutableArray alloc] init];
        vertCount = vCount;
        normals = vNormals;
        bounds = [[Bounds alloc] initWithEntity:self];
    }
    
    return self;
}

- (void)update:(float)deltaTime;
{
    for (Entity *child in children)
    {
        [child update:deltaTime];
    }
}

- (void)draw:(Engine *)engine:(Camera *)cam
{
    if ([cam isVisible:bounds])
    {
        //[bounds draw:engine];
        [self applyTransform:engine];
        
        
        if (vertCount > 0)
        {
            if (colors != nil && texture != nil)
            {
                [engine drawGeometry:vertices vertCount:vertCount withColor:colors withTexture:texture setUVs:uvs setNormals:normals];
            }
            else if (colors != nil)
            {
                [engine drawGeometry:vertices vertCount:vertCount withColor:colors];
            }
            else if (texture != nil)
            {
                [engine drawGeometry:vertices vertCount:vertCount withTexture:texture setUVs:uvs setNormals:normals];
            }
        }
        
        for (int i= 0; i < [children count]; i++)
        {
            Entity *child = [children objectAtIndex:i];
            [child draw:engine:cam];
        }
        
        [self resetTransform:engine];
    }
    else
    {
        //NSLog(@"NOT VISIBLE: %@", name);
    }
}

-(void)merge:(Entity *)ent1
{
    if (ent1 == nil)
        return;
    
    if (ent1.vertCount == 0)
        return;
    
    GLfloat *verts = malloc(sizeof(GLfloat)*3*(self.vertCount + ent1.vertCount));
    int idx = 0;
    for (int i = 0; i < vertCount*3; i++)
    {
        verts[idx] = self.vertices[i];
        idx++;
    }
    
    for (int i = 0; i < ent1.vertCount*3; i++)
    {
        verts[idx] = ent1.vertices[i];
        idx++;
    }     
    vertices = verts;
    
    GLfloat *newUVs = malloc(sizeof(GLfloat)*2*(self.vertCount + ent1.vertCount));
    idx = 0;
    for (int i = 0; i < vertCount*2; i++)
    {
        newUVs[idx] = self.uvs[i];
        idx++;
    }
    
    for (int i = 0; i < ent1.vertCount*2; i++)
    {
        newUVs[idx] = ent1.uvs[i];
        idx++;
    }
    
    uvs = newUVs;
    
    GLfloat *newNormals = malloc(sizeof(GLfloat)*3*(self.vertCount + ent1.vertCount));
    idx = 0;
    for (int i = 0; i < vertCount*3; i++)
    {
        newNormals[idx] = self.normals[i];
        idx++;
    }
    
    for (int i = 0; i < ent1.vertCount*3; i++)
    {
        newNormals[idx] = ent1.normals[i];
        idx++;
    }
    normals = newNormals;
    
    vertCount += ent1.vertCount;
    
    if (self.texture == nil)
        texture = ent1.texture;
    
    bounds = [bounds initWithEntity:self];
    
    Entity *child;
    for (child in ent1.children)
        [self addChild:child];
}

- (void)updateBounds
{
    bounds = [bounds initWithEntity:self];
}

- (void)move:(Vector3 *)movement
{
    position[0] += [movement getX];
    position[1] += [movement getY];
    position[2] += [movement getZ];
}

- (void)dealloc
{
    free(vertices);
    free(colors);
    free(texture);
    free(uvs);
    [bounds release];
    free(normals);
    [super dealloc];
}
@end
